<?php
/**
* Controls for the "model-binding" UI widget.
*
* Usage (javascript, to display the widget):
* <input type="hidden" name="TEST" rel="scribble-widget"
*		scribblewidget:type="model-binding"
*		scribblewidget:config="targetModel=ModelNameHere"
*		value="<?php $this->html->e(ScribbleBindingWidget::getBindings($sourceModel, 'ModelNameHere', 'binding-ref-here')); ?>" />
*
* Usage (PHP, when form containing the above widget is POSTed):
*		$bindings = ScribbleBindingWidget::gatherBindingsFromPost($sourceModel, $_POST['TEST'], $ref);
*
* Usage (PHP, to save the gathered bindings gathered above):
*		ScribbleBindingWidget::saveGatheredBindings($sourceModel, $bindings);
*
* Copyright (c) 2009 James Gauld <james@jamesgauld.net>
* This file is part of Scribble.
* @license http://www.scribblecms.co.uk/license.txt
*
* @package Scribble
*/
use Buan\Config;
use Buan\Model;
use Buan\ModelCriteria;
use Buan\ModelManager;
class ScribbleBindingWidget {

	/**
	* Returns information about the bindings between $source and models of type
	* $targetModel under the given reference.
	*
	* The result of this method is a JSON-encoded StdClass instance.
	*
	* @param ScribbleModel The source model
	* @param string The target model
	* @param string Binding reference
	* @return string
	*/
	static public function getBindings($source, $targetModelName, $ref) {

		// Prepare result
		$data = (object)array(
			'models'=>array()
		);

		// Find all existing bindings
		$models = ScribbleBinding::findModels($source->id, $targetModelName, $ref);
		foreach($models as $m) {
			$data->models[] = $m->idMeta();
		}

		// Result
		return json_encode($data);
	}

	/**
	* Returns an array containing all the BindingModel instances that bind
	* $source and all selected targets together under the given reference.
	*
	* Use this in conjunction with self::saveGatheredBindings() to submit these
	* bindings to the database.
	*
	* @param ScribbleModel Source model to which the bindings will be added
	* @param string JSON-encoded bindings data (from your POST variable)
	* @param string Binding reference
	* @return array
	*/
	public static function gatherBindingsFromPost($source, $bindings, $ref) {
		$result = array();
		$bindings = json_decode($bindings);
		foreach($bindings->models as $m) {
			$b = Model::create('Binding');
			$b->ref = $ref;
			$b->source_id = $source->id;
			$b->source_model = $source->modelName;
			$b->target_id = $m->id;
			$b->target_model = $m->modelName;
			$result[] = $b;
		}
		return $result;
	}

	/**
	* Save the BindingModel instances that were created from the POSTed widget
	* data to the database.
	*
	* $bindings is the result of ScribbleBindingWidget::gatherBindingsFromPost()
	*
	* When the bindings are saved, their "source_id" field is set to $source->id
	* as by this point, as long as this method was called in the correct place, we
	* can be sure that $source has been saved to the db so has an id.
	*
	* @param ScribbleModel Source model
	* @param array Array of BindingModel instances
	* @return void
	*/
	public static function saveGatheredBindings($source, $bindings) {
		if(!empty($bindings)) {

			// Remove all existing bindings to avoid creating duplicates
			$dbTblPrefix = Config::get('ext.Scribble.dbTablePrefix');
			ModelManager::sqlQuery("DELETE FROM {$dbTblPrefix}binding WHERE source_id=? AND ref=?", array($source->id, $bindings[0]->ref));

			// Save all new bindings
			foreach($bindings as $b) {
				$b->source_id = $source->id;
				$b->getModelManager()->save($b);
			}
		}
	}
}
?>